package com.uniflow.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.uniflow.common.PageResult;
import com.uniflow.common.Result;
import com.uniflow.common.ResultCode;
import com.uniflow.entity.SystemConfig;
import com.uniflow.service.SystemConfigService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotEmpty;
import java.util.List;
import java.util.Map;

/**
 * 系统配置管理控制器
 * 
 * @author uniflow
 * @since 1.0.0
 */
@RestController
@RequestMapping("/api/v1/system-configs")
@Validated
@Api(tags = "系统配置管理")
public class SystemConfigController {
    
    @Autowired
    private SystemConfigService systemConfigService;
    
    /**
     * 分页查询系统配置列表
     */
    @GetMapping
    @PreAuthorize("hasAuthority('config:read')")
    @ApiOperation("分页查询系统配置列表")
    public Result<PageResult<SystemConfig>> getConfigList(
            @ApiParam("页码") @RequestParam(defaultValue = "1") int pageNum,
            @ApiParam("页大小") @RequestParam(defaultValue = "10") int pageSize,
            @ApiParam("配置分类") @RequestParam(required = false) String category,
            @ApiParam("配置类型") @RequestParam(required = false) String configType,
            @ApiParam("是否公开") @RequestParam(required = false) Boolean isPublic,
            @ApiParam("是否加密") @RequestParam(required = false) Boolean isEncrypted,
            @ApiParam("关键词") @RequestParam(required = false) String keyword) {
        try {
            IPage<SystemConfig> page = systemConfigService.getConfigPage(pageNum, pageSize, category, configType, isPublic, isEncrypted, keyword);
            PageResult<SystemConfig> result = new PageResult<SystemConfig>(pageNum, pageSize, page.getTotal(), page.getRecords());
            return Result.success(result);
        } catch (Exception e) {
            return Result.error(ResultCode.ERROR, e.getMessage());
        }
    }
    
    /**
     * 根据ID查询配置详情
     */
    @GetMapping("/{id}")
    @PreAuthorize("hasAuthority('config:read')")
    @ApiOperation("根据ID查询配置详情")
    public Result<SystemConfig> getConfigById(@ApiParam("配置ID") @PathVariable String id) {
        try {
            SystemConfig config = systemConfigService.getConfigById(id);
            if (config == null) {
                return Result.error(ResultCode.NOT_FOUND, "配置不存在");
            }
            return Result.success(config);
        } catch (Exception e) {
            return Result.error(ResultCode.ERROR, e.getMessage());
        }
    }
    
    /**
     * 根据配置键查询配置
     */
    @GetMapping("/key/{configKey}")
    @PreAuthorize("hasAuthority('config:read')")
    @ApiOperation("根据配置键查询配置")
    public Result<SystemConfig> getConfigByKey(@ApiParam("配置键") @PathVariable String configKey) {
        try {
            SystemConfig config = systemConfigService.getConfigByKey(configKey);
            if (config == null) {
                return Result.error(ResultCode.NOT_FOUND, "配置不存在");
            }
            return Result.success(config);
        } catch (Exception e) {
            return Result.error(ResultCode.ERROR, e.getMessage());
        }
    }
    
    /**
     * 获取配置值
     */
    @GetMapping("/value/{configKey}")
    @PreAuthorize("hasAuthority('config:read')")
    @ApiOperation("获取配置值")
    public Result<String> getConfigValue(@ApiParam("配置键") @PathVariable String configKey) {
        try {
            String value = systemConfigService.getConfigValue(configKey);
            return Result.success(value);
        } catch (Exception e) {
            return Result.error(ResultCode.ERROR, e.getMessage());
        }
    }
    
    /**
     * 获取解密后的配置值
     */
    @GetMapping("/decrypted-value/{configKey}")
    @PreAuthorize("hasAuthority('config:read')")
    @ApiOperation("获取解密后的配置值")
    public Result<String> getDecryptedConfigValue(@ApiParam("配置键") @PathVariable String configKey) {
        try {
            String value = systemConfigService.getDecryptedConfigValue(configKey);
            return Result.success(value);
        } catch (Exception e) {
            return Result.error(ResultCode.ERROR, e.getMessage());
        }
    }
    
    /**
     * 根据分类查询配置
     */
    @GetMapping("/category/{category}")
    @PreAuthorize("hasAuthority('config:read')")
    @ApiOperation("根据分类查询配置")
    public Result<List<SystemConfig>> getConfigsByCategory(@ApiParam("配置分类") @PathVariable String category) {
        try {
            List<SystemConfig> configs = systemConfigService.getConfigsByCategory(category);
            return Result.success(configs);
        } catch (Exception e) {
            return Result.error(ResultCode.ERROR, e.getMessage());
        }
    }
    
    /**
     * 查询公开配置
     */
    @GetMapping("/public")
    @ApiOperation("查询公开配置")
    public Result<List<SystemConfig>> getPublicConfigs() {
        try {
            List<SystemConfig> configs = systemConfigService.getPublicConfigs();
            return Result.success(configs);
        } catch (Exception e) {
            return Result.error(ResultCode.ERROR, e.getMessage());
        }
    }
    
    /**
     * 查询私有配置
     */
    @GetMapping("/private")
    @PreAuthorize("hasAuthority('config:read')")
    @ApiOperation("查询私有配置")
    public Result<List<SystemConfig>> getPrivateConfigs() {
        try {
            List<SystemConfig> configs = systemConfigService.getPrivateConfigs();
            return Result.success(configs);
        } catch (Exception e) {
            return Result.error(ResultCode.ERROR, e.getMessage());
        }
    }
    
    /**
     * 根据配置类型查询
     */
    @GetMapping("/type/{configType}")
    @PreAuthorize("hasAuthority('config:read')")
    @ApiOperation("根据配置类型查询")
    public Result<List<SystemConfig>> getConfigsByType(@ApiParam("配置类型") @PathVariable String configType) {
        try {
            List<SystemConfig> configs = systemConfigService.getConfigsByType(configType);
            return Result.success(configs);
        } catch (Exception e) {
            return Result.error(ResultCode.ERROR, e.getMessage());
        }
    }
    
    /**
     * 批量查询配置
     */
    @PostMapping("/batch")
    @PreAuthorize("hasAuthority('config:read')")
    @ApiOperation("批量查询配置")
    public Result<List<SystemConfig>> getConfigsByKeys(@RequestBody @NotEmpty List<String> configKeys) {
        try {
            List<SystemConfig> configs = systemConfigService.getConfigsByKeys(configKeys);
            return Result.success(configs);
        } catch (Exception e) {
            return Result.error(ResultCode.ERROR, e.getMessage());
        }
    }
    
    /**
     * 查询配置分类列表
     */
    @GetMapping("/categories")
    @PreAuthorize("hasAuthority('config:read')")
    @ApiOperation("查询配置分类列表")
    public Result<List<String>> getCategories() {
        try {
            List<String> categories = systemConfigService.getCategories();
            return Result.success(categories);
        } catch (Exception e) {
            return Result.error(ResultCode.ERROR, e.getMessage());
        }
    }
    
    /**
     * 查询配置类型列表
     */
    @GetMapping("/types")
    @PreAuthorize("hasAuthority('config:read')")
    @ApiOperation("查询配置类型列表")
    public Result<List<String>> getConfigTypes() {
        try {
            List<String> types = systemConfigService.getConfigTypes();
            return Result.success(types);
        } catch (Exception e) {
            return Result.error(ResultCode.ERROR, e.getMessage());
        }
    }
    
    /**
     * 创建配置
     */
    @PostMapping
    @PreAuthorize("hasAuthority('config:write')")
    @ApiOperation("创建配置")
    public Result<SystemConfig> createConfig(@Valid @RequestBody CreateConfigRequest request) {
        try {
            SystemConfig config = new SystemConfig();
            config.setConfigKey(request.getConfigKey());
            config.setConfigValue(request.getConfigValue());
            config.setConfigType(request.getConfigType());
            config.setCategory(request.getCategory());
            config.setDescription(request.getDescription());
            config.setIsPublic(request.getIsPublic());
            config.setIsEncrypted(request.getIsEncrypted());
            config.setSortOrder(request.getSortOrder());
            
            SystemConfig createdConfig = systemConfigService.createConfig(config);
            return Result.success(createdConfig);
        } catch (Exception e) {
            return Result.error(ResultCode.ERROR, e.getMessage());
        }
    }
    
    /**
     * 更新配置
     */
    @PutMapping("/{id}")
    @PreAuthorize("hasAuthority('config:write')")
    @ApiOperation("更新配置")
    public Result<SystemConfig> updateConfig(
            @ApiParam("配置ID") @PathVariable String id,
            @Valid @RequestBody UpdateConfigRequest request) {
        try {
            SystemConfig config = new SystemConfig();
            config.setId(id);
            config.setConfigKey(request.getConfigKey());
            config.setConfigValue(request.getConfigValue());
            config.setConfigType(request.getConfigType());
            config.setCategory(request.getCategory());
            config.setDescription(request.getDescription());
            config.setIsPublic(request.getIsPublic());
            config.setIsEncrypted(request.getIsEncrypted());
            config.setSortOrder(request.getSortOrder());
            
            SystemConfig updatedConfig = systemConfigService.updateConfig(config);
            return Result.success(updatedConfig);
        } catch (Exception e) {
            return Result.error(ResultCode.ERROR, e.getMessage());
        }
    }
    
    /**
     * 更新配置值
     */
    @PutMapping("/value/{configKey}")
    @PreAuthorize("hasAuthority('config:write')")
    @ApiOperation("更新配置值")
    public Result<Void> updateConfigValue(
            @ApiParam("配置键") @PathVariable String configKey,
            @RequestBody UpdateConfigValueRequest request) {
        try {
            systemConfigService.updateConfigValue(configKey, request.getConfigValue());
            return Result.success();
        } catch (Exception e) {
            return Result.error(ResultCode.ERROR, e.getMessage());
        }
    }
    
    /**
     * 删除配置
     */
    @DeleteMapping("/{id}")
    @PreAuthorize("hasAuthority('config:write')")
    @ApiOperation("删除配置")
    public Result<Void> deleteConfig(@ApiParam("配置ID") @PathVariable String id) {
        try {
            systemConfigService.deleteConfig(id);
            return Result.success();
        } catch (Exception e) {
            return Result.error(ResultCode.ERROR, e.getMessage());
        }
    }
    
    /**
     * 批量删除配置
     */
    @DeleteMapping
    @PreAuthorize("hasAuthority('config:write')")
    @ApiOperation("批量删除配置")
    public Result<Void> deleteConfigs(@RequestBody @NotEmpty List<String> ids) {
        try {
            systemConfigService.deleteConfigs(ids);
            return Result.success();
        } catch (Exception e) {
            return Result.error(ResultCode.ERROR, e.getMessage());
        }
    }
    
    /**
     * 查询配置统计信息
     */
    @GetMapping("/stats")
    @PreAuthorize("hasAuthority('config:read')")
    @ApiOperation("查询配置统计信息")
    public Result<Map<String, Object>> getConfigStats() {
        try {
            Map<String, Object> stats = systemConfigService.getConfigStats();
            return Result.success(stats);
        } catch (Exception e) {
            return Result.error(ResultCode.ERROR, e.getMessage());
        }
    }
    
    /**
     * 查询分类配置统计
     */
    @GetMapping("/stats/category")
    @PreAuthorize("hasAuthority('config:read')")
    @ApiOperation("查询分类配置统计")
    public Result<List<Map<String, Object>>> getCategoryStats() {
        try {
            List<Map<String, Object>> stats = systemConfigService.getCategoryStats();
            return Result.success(stats);
        } catch (Exception e) {
            return Result.error(ResultCode.ERROR, e.getMessage());
        }
    }
    
    /**
     * 查询类型配置统计
     */
    @GetMapping("/stats/type")
    @PreAuthorize("hasAuthority('config:read')")
    @ApiOperation("查询类型配置统计")
    public Result<List<Map<String, Object>>> getTypeStats() {
        try {
            List<Map<String, Object>> stats = systemConfigService.getTypeStats();
            return Result.success(stats);
        } catch (Exception e) {
            return Result.error(ResultCode.ERROR, e.getMessage());
        }
    }
    
    /**
     * 查询最近更新的配置
     */
    @GetMapping("/recent/updated")
    @PreAuthorize("hasAuthority('config:read')")
    @ApiOperation("查询最近更新的配置")
    public Result<List<SystemConfig>> getRecentUpdated(
            @ApiParam("限制数量") @RequestParam(defaultValue = "10") Integer limit) {
        try {
            List<SystemConfig> recent = systemConfigService.getRecentUpdated(limit);
            return Result.success(recent);
        } catch (Exception e) {
            return Result.error(ResultCode.ERROR, e.getMessage());
        }
    }
    
    /**
     * 查询最近创建的配置
     */
    @GetMapping("/recent/created")
    @PreAuthorize("hasAuthority('config:read')")
    @ApiOperation("查询最近创建的配置")
    public Result<List<SystemConfig>> getRecentCreated(
            @ApiParam("限制数量") @RequestParam(defaultValue = "10") Integer limit) {
        try {
            List<SystemConfig> recent = systemConfigService.getRecentCreated(limit);
            return Result.success(recent);
        } catch (Exception e) {
            return Result.error(ResultCode.ERROR, e.getMessage());
        }
    }
    
    /**
     * 查询配置变更历史
     */
    @GetMapping("/{configKey}/history")
    @PreAuthorize("hasAuthority('config:read')")
    @ApiOperation("查询配置变更历史")
    public Result<List<Map<String, Object>>> getChangeHistory(
            @ApiParam("配置键") @PathVariable String configKey,
            @ApiParam("开始日期") @RequestParam(required = false) String startDate,
            @ApiParam("结束日期") @RequestParam(required = false) String endDate) {
        try {
            List<Map<String, Object>> history = systemConfigService.getChangeHistory(configKey, startDate, endDate);
            return Result.success(history);
        } catch (Exception e) {
            return Result.error(ResultCode.ERROR, e.getMessage());
        }
    }
    
    /**
     * 查询未使用的配置
     */
    @GetMapping("/unused")
    @PreAuthorize("hasAuthority('config:read')")
    @ApiOperation("查询未使用的配置")
    public Result<List<SystemConfig>> getUnusedConfigs() {
        try {
            List<SystemConfig> unused = systemConfigService.getUnusedConfigs();
            return Result.success(unused);
        } catch (Exception e) {
            return Result.error(ResultCode.ERROR, e.getMessage());
        }
    }
    
    /**
     * 重置配置到默认值
     */
    @PutMapping("/reset/{configKey}")
    @PreAuthorize("hasAuthority('config:write')")
    @ApiOperation("重置配置到默认值")
    public Result<Void> resetToDefault(@ApiParam("配置键") @PathVariable String configKey) {
        try {
            systemConfigService.resetToDefault(configKey);
            return Result.success();
        } catch (Exception e) {
            return Result.error(ResultCode.ERROR, e.getMessage());
        }
    }
    
    /**
     * 批量重置配置
     */
    @PutMapping("/reset/batch")
    @PreAuthorize("hasAuthority('config:write')")
    @ApiOperation("批量重置配置")
    public Result<Void> batchResetToDefault(@RequestBody @NotEmpty List<String> configKeys) {
        try {
            systemConfigService.batchResetToDefault(configKeys);
            return Result.success();
        } catch (Exception e) {
            return Result.error(ResultCode.ERROR, e.getMessage());
        }
    }
    
    /**
     * 导出配置数据
     */
    @PostMapping("/export")
    @PreAuthorize("hasAuthority('config:read')")
    @ApiOperation("导出配置数据")
    public Result<List<SystemConfig>> exportConfigs(@RequestBody ExportConfigRequest request) {
        try {
            List<SystemConfig> configs = systemConfigService.exportConfigs(
                    request.getCategories(), request.getIncludePrivate(), request.getIncludeEncrypted());
            return Result.success(configs);
        } catch (Exception e) {
            return Result.error(ResultCode.ERROR, e.getMessage());
        }
    }
    
    /**
     * 导入配置数据
     */
    @PostMapping("/import")
    @PreAuthorize("hasAuthority('config:write')")
    @ApiOperation("导入配置数据")
    public Result<Void> importConfigs(@RequestBody @NotEmpty List<SystemConfig> configs) {
        try {
            systemConfigService.importConfigs(configs);
            return Result.success();
        } catch (Exception e) {
            return Result.error(ResultCode.ERROR, e.getMessage());
        }
    }
    
    /**
     * 初始化系统默认配置
     */
    @PostMapping("/init-defaults")
    @PreAuthorize("hasAuthority('config:write')")
    @ApiOperation("初始化系统默认配置")
    public Result<Void> initDefaultConfigs() {
        try {
            systemConfigService.initDefaultConfigs();
            return Result.success();
        } catch (Exception e) {
            return Result.error(ResultCode.ERROR, e.getMessage());
        }
    }
    
    // ==================== 请求数据结构 ====================
    
    public static class CreateConfigRequest {
        @NotBlank(message = "配置键不能为空")
        private String configKey;
        
        @NotBlank(message = "配置值不能为空")
        private String configValue;
        
        @NotBlank(message = "配置类型不能为空")
        private String configType;
        
        private String category;
        private String description;
        private Boolean isPublic = false;
        private Boolean isEncrypted = false;
        private Integer sortOrder = 0;
        
        // getters and setters
        public String getConfigKey() { return configKey; }
        public void setConfigKey(String configKey) { this.configKey = configKey; }
        public String getConfigValue() { return configValue; }
        public void setConfigValue(String configValue) { this.configValue = configValue; }
        public String getConfigType() { return configType; }
        public void setConfigType(String configType) { this.configType = configType; }
        public String getCategory() { return category; }
        public void setCategory(String category) { this.category = category; }
        public String getDescription() { return description; }
        public void setDescription(String description) { this.description = description; }
        public Boolean getIsPublic() { return isPublic; }
        public void setIsPublic(Boolean isPublic) { this.isPublic = isPublic; }
        public Boolean getIsEncrypted() { return isEncrypted; }
        public void setIsEncrypted(Boolean isEncrypted) { this.isEncrypted = isEncrypted; }
        public Integer getSortOrder() { return sortOrder; }
        public void setSortOrder(Integer sortOrder) { this.sortOrder = sortOrder; }
    }
    
    public static class UpdateConfigRequest {
        @NotBlank(message = "配置键不能为空")
        private String configKey;
        
        @NotBlank(message = "配置值不能为空")
        private String configValue;
        
        @NotBlank(message = "配置类型不能为空")
        private String configType;
        
        private String category;
        private String description;
        private Boolean isPublic;
        private Boolean isEncrypted;
        private Integer sortOrder;
        
        // getters and setters
        public String getConfigKey() { return configKey; }
        public void setConfigKey(String configKey) { this.configKey = configKey; }
        public String getConfigValue() { return configValue; }
        public void setConfigValue(String configValue) { this.configValue = configValue; }
        public String getConfigType() { return configType; }
        public void setConfigType(String configType) { this.configType = configType; }
        public String getCategory() { return category; }
        public void setCategory(String category) { this.category = category; }
        public String getDescription() { return description; }
        public void setDescription(String description) { this.description = description; }
        public Boolean getIsPublic() { return isPublic; }
        public void setIsPublic(Boolean isPublic) { this.isPublic = isPublic; }
        public Boolean getIsEncrypted() { return isEncrypted; }
        public void setIsEncrypted(Boolean isEncrypted) { this.isEncrypted = isEncrypted; }
        public Integer getSortOrder() { return sortOrder; }
        public void setSortOrder(Integer sortOrder) { this.sortOrder = sortOrder; }
    }
    
    public static class UpdateConfigValueRequest {
        @NotBlank(message = "配置值不能为空")
        private String configValue;
        
        // getters and setters
        public String getConfigValue() { return configValue; }
        public void setConfigValue(String configValue) { this.configValue = configValue; }
    }
    
    public static class ExportConfigRequest {
        private List<String> categories;
        private Boolean includePrivate = false;
        private Boolean includeEncrypted = false;
        
        // getters and setters
        public List<String> getCategories() { return categories; }
        public void setCategories(List<String> categories) { this.categories = categories; }
        public Boolean getIncludePrivate() { return includePrivate; }
        public void setIncludePrivate(Boolean includePrivate) { this.includePrivate = includePrivate; }
        public Boolean getIncludeEncrypted() { return includeEncrypted; }
        public void setIncludeEncrypted(Boolean includeEncrypted) { this.includeEncrypted = includeEncrypted; }
    }
}